var CONSOLE = Components.classes["@mozilla.org/consoleservice;1"]
                                 .getService(Components.interfaces.nsIConsoleService);
								 
function consoleLog(msg)
{
	CONSOLE.logStringMessage("downloadTabs: " + msg);
}

function getExtensionManager()
{
	var em = Components.classes["@mozilla.org/extensions/manager;1"]
			.getService(Components.interfaces.nsIExtensionManager);
	return(em);
}

function getExtensionPath()
{
	var MY_ID = "downloadtabs@jeff.c";  
	  
	// the path may use forward slash ("/") as the delimiter  
	// returns nsIFile for the extension's install.rdf  
	var file = getExtensionManager().getInstallLocation(MY_ID).getItemFile(MY_ID, "install.rdf");
	return(file.parent);
}

// Was used for sidebar detection
function getExtensionList()
{
	var items = getExtensionManager().getItemList(Components.interfaces.nsIUpdateItem.TYPE_ANY, { });
	return(items);
}

function preloadImage(img)
{
	myimage = new Image();
	myimage.src = img;
}

function preloadImages()
{
	var myimages = new Array();
	for(var i = 0; i < arguments.length; i++)
	{
		myimages[i] = new Image();
		myimages[i].src = arguments[i];
	}
}

// From http://magnetiq.com/2006/07/10/finding-out-class-names-of-javascript-objects/
function getObjectClass(obj)
{  
    if(obj && obj.constructor && obj.constructor.toString)
	{  
        var arr = obj.constructor.toString().match(/function\s*(\w+)/);  
  
        i (arr && arr.length == 2)
		{
            return arr[1];  
        }  
    }  
  
    return undefined;  
}  

function getXBLElementsByClassName(myDocument, parent, className, list)
{
	if(!parent)
	{
		//consoleLog("getXBLElementsByClassName ret parent");
		return;
	}
	if(parent.hasChildNodes())
	{
		var elements = parent.childNodes;
		for(var i = 0; i < elements.length; i++)
		{
			if(elements.item(i))
			{
				//if(elements.item(i).classList.contains(className))
				if(elements.item(i).getAttribute("class").indexOf(className) != -1)
				{
					consoleLog("classList match: [" + elements.item(i).classList + "], " + className);
					list.push(elements.item(i));
				}
			}
			getXBLElementsByClassName(myDocument, elements.item(i), className, list);
		}
	}
	
	var hidden = myDocument.getAnonymousNodes(parent);
	if(!hidden || hidden.length == 0)
	{
		//consoleLog("getXBLElementsByClassName ret hidden");
		return;
	}
	for(var i = 0; i < hidden.length; i++)
	{
		if(hidden.item(i))
		{
			//if(hidden.item(i).classList.contains(className))
			if(hidden.item(i).getAttribute("class").indexOf(className) != -1)
			{
				list.push(hidden.item(i));
			}
		}
		getXBLElementsByClassName(myDocument, hidden.item(i), className, list);
	}
	return(list);
}

// Convert a size or speed to human readable format
function sizeReadable(size)
{
	var ret = "";
	if(size)
	{
		var places = Math.log(size) / Math.log(10);
		var prefix = Math.floor(places / 3);
		
		// Engineering notation
		ret += size / Math.pow(10, prefix * 3);
		
		// Round size
		var rounding = dlTabsPrefs.getDisplayPref("sizeRound");
		if(ret.length > rounding)
			ret = ret.substring(0, rounding);
		
		// Since it's a standard, there's no locale or stringbundle
		switch(prefix)
		{
			case 0:		/* no prefix */		break;
			case 1:		ret += "K";			break;	// Kilo
			case 2:		ret += "M";			break;	// Mega
			case 3:		ret += "G";			break;	// Giga
			case 4:		ret += "T";			break;	// Tera
			case 5:		ret += "P";			break;	// Peta
			case 6:		ret += "E";			break;	// Exa
			case 7:		ret += "Z";			break;	// Zetta
			case 8:		ret += "Y";			break;	// Yotta
			// Not official SI prefixes
			case 8:		ret += "X";			break;	// Xona
			case 9:		ret += "W";			break;	// Weka
			case 10:	ret += "V";			break;	// Vunda
			case 11:	ret += "U";			break;	// Uda
			case 12:	ret += "TD";		break;	// Treda
			case 13:	ret += "S";			break;	// Sorta
			case 14:	ret += "R";			break;	// Rinta
			case 15:	ret += "Q";			break;	// Quexa
			case 16:	ret += "PP";		break;	// Pepta
			case 17:	ret += "O";			break;	// Ocha
			case 18:	ret += "N";			break;	// Nena
			case 19:	ret += "MI";		break;	// Minga
			case 20:	ret += "L";			break;	// Luma
			// This will probably keep me convered for the next few decades
		}
	}
	else
		ret = "0";
		
	ret += "B";
	
	return(ret);
}